package auth

import (
	"crypto/subtle"
	"net/http"
	"sync"
)

type Authenticator struct {
	users   map[string]string
	realm   string
	enabled bool
	mu      sync.RWMutex
}

func NewAuthenticator(realm string) *Authenticator {
	return &Authenticator{
		users:   make(map[string]string),
		realm:   realm,
		enabled: true,
	}
}

func (a *Authenticator) AddUser(username, password string) {
	a.mu.Lock()
	defer a.mu.Unlock()
	a.users[username] = password
}

func (a *Authenticator) RemoveUser(username string) {
	a.mu.Lock()
	defer a.mu.Unlock()
	delete(a.users, username)
}

func (a *Authenticator) SetEnabled(enabled bool) {
	a.mu.Lock()
	defer a.mu.Unlock()
	a.enabled = enabled
}

func (a *Authenticator) Middleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		a.mu.RLock()
		enabled := a.enabled
		a.mu.RUnlock()

		if !enabled {
			next.ServeHTTP(w, r)
			return
		}

		user, pass, ok := r.BasicAuth()
		if !ok {
			w.Header().Set("WWW-Authenticate", `Basic realm="`+a.realm+`"`)
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

		a.mu.RLock()
		expectedPass, exists := a.users[user]
		a.mu.RUnlock()

		if !exists || subtle.ConstantTimeCompare([]byte(pass), []byte(expectedPass)) != 1 {
			w.Header().Set("WWW-Authenticate", `Basic realm="`+a.realm+`"`)
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

		next.ServeHTTP(w, r)
	})
}

// OAuth2 support will be added here
type OAuth2Config struct {
	ClientID     string
	ClientSecret string
	RedirectURL  string
	Scopes       []string
}

// JWT support will be added here
type JWTConfig struct {
	SecretKey    []byte
	TokenTimeout int64
}

// TODO: Implement OAuth2 and JWT authentication methods
